package com.teacher.game.framework.util;

import android.util.Log;

/**
 * 性能监控器 - 实时监控游戏性能指标
 * 监控FPS、内存使用、渲染时间等关键性能参数
 */
public class PerformanceMonitor {
    
    private static final String TAG = "PerformanceMonitor";
    private static PerformanceMonitor instance;
    
    // FPS 监控
    private long lastFrameTime = 0;
    private int frameCount = 0;
    private float currentFPS = 0;
    private float targetFPS = 60.0f;
    private long fpsUpdateInterval = 1000; // 1秒更新一次FPS
    private long lastFpsUpdate = 0;
    
    // 渲染时间监控
    private long renderStartTime = 0;
    private float averageRenderTime = 0;
    private float maxRenderTime = 0;
    private int renderSampleCount = 0;
    private static final int RENDER_SAMPLE_SIZE = 60; // 采样60帧计算平均值
    
    // 内存监控
    private long lastMemoryCheck = 0;
    private long memoryCheckInterval = 5000; // 5秒检查一次内存
    private float currentMemoryUsage = 0;
    private float maxMemoryUsage = 0;
    
    // 性能警告阈值
    private static final float FPS_WARNING_THRESHOLD = 45.0f;
    private static final float RENDER_WARNING_THRESHOLD = 20.0f; // 20ms
    private static final float MEMORY_WARNING_THRESHOLD = 0.8f; // 80%内存使用率
    
    // 统计数据
    private int totalFrames = 0;
    private long startTime = 0;
    private int fpsWarnings = 0;
    private int renderWarnings = 0;
    private int memoryWarnings = 0;
    
    /**
     * 私有构造函数
     */
    private PerformanceMonitor() {
        startTime = System.currentTimeMillis();
        Log.d(TAG, "性能监控器已启动");
    }
    
    /**
     * 获取单例实例
     * @return PerformanceMonitor实例
     */
    public static synchronized PerformanceMonitor getInstance() {
        if (instance == null) {
            instance = new PerformanceMonitor();
        }
        return instance;
    }
    
    /**
     * 帧开始 - 在每帧开始时调用
     */
    public void frameStart() {
        long currentTime = System.currentTimeMillis();
        renderStartTime = currentTime;
        
        // 计算FPS
        if (lastFrameTime == 0) {
            lastFrameTime = currentTime;
        }
        
        frameCount++;
        totalFrames++;
        
        // 更新FPS
        if (currentTime - lastFpsUpdate >= fpsUpdateInterval) {
            currentFPS = frameCount * 1000.0f / (currentTime - lastFpsUpdate);
            frameCount = 0;
            lastFpsUpdate = currentTime;
            
            // FPS警告检查
            if (currentFPS < FPS_WARNING_THRESHOLD) {
                fpsWarnings++;
                Log.w(TAG, "FPS过低警告: " + String.format("%.1f", currentFPS) + " FPS");
            }
        }
        
        // 内存检查
        if (currentTime - lastMemoryCheck >= memoryCheckInterval) {
            checkMemoryUsage();
            lastMemoryCheck = currentTime;
        }
    }
    
    /**
     * 帧结束 - 在每帧结束时调用
     */
    public void frameEnd() {
        long renderTime = System.currentTimeMillis() - renderStartTime;
        
        // 更新渲染时间统计
        if (renderSampleCount < RENDER_SAMPLE_SIZE) {
            averageRenderTime = (averageRenderTime * renderSampleCount + renderTime) / (renderSampleCount + 1);
            renderSampleCount++;
        } else {
            // 滑动平均
            averageRenderTime = averageRenderTime * 0.95f + renderTime * 0.05f;
        }
        
        // 更新最大渲染时间
        if (renderTime > maxRenderTime) {
            maxRenderTime = renderTime;
        }
        
        // 渲染时间警告检查
        if (renderTime > RENDER_WARNING_THRESHOLD) {
            renderWarnings++;
            Log.w(TAG, "渲染时间过长警告: " + renderTime + "ms");
        }
        
        lastFrameTime = System.currentTimeMillis();
    }
    
    /**
     * 检查内存使用情况
     */
    private void checkMemoryUsage() {
        Runtime runtime = Runtime.getRuntime();
        long usedMemory = runtime.totalMemory() - runtime.freeMemory();
        long maxMemory = runtime.maxMemory();
        
        currentMemoryUsage = (float) usedMemory / maxMemory;
        
        if (currentMemoryUsage > maxMemoryUsage) {
            maxMemoryUsage = currentMemoryUsage;
        }
        
        // 内存警告检查
        if (currentMemoryUsage > MEMORY_WARNING_THRESHOLD) {
            memoryWarnings++;
            Log.w(TAG, "内存使用率过高警告: " + String.format("%.1f", currentMemoryUsage * 100) + "%");
        }
        
        Log.d(TAG, "内存使用: " + formatBytes(usedMemory) + "/" + formatBytes(maxMemory) + 
              " (" + String.format("%.1f", currentMemoryUsage * 100) + "%)");
    }
    
    /**
     * 格式化字节数
     * @param bytes 字节数
     * @return 格式化字符串
     */
    private String formatBytes(long bytes) {
        if (bytes < 1024) return bytes + "B";
        if (bytes < 1024 * 1024) return String.format("%.1fKB", bytes / 1024.0f);
        return String.format("%.1fMB", bytes / (1024.0f * 1024.0f));
    }
    
    /**
     * 获取当前FPS
     * @return 当前FPS
     */
    public float getCurrentFPS() {
        return currentFPS;
    }
    
    /**
     * 获取平均渲染时间
     * @return 平均渲染时间（毫秒）
     */
    public float getAverageRenderTime() {
        return averageRenderTime;
    }
    
    /**
     * 获取最大渲染时间
     * @return 最大渲染时间（毫秒）
     */
    public float getMaxRenderTime() {
        return maxRenderTime;
    }
    
    /**
     * 获取当前内存使用率
     * @return 内存使用率 (0.0-1.0)
     */
    public float getCurrentMemoryUsage() {
        return currentMemoryUsage;
    }
    
    /**
     * 获取最大内存使用率
     * @return 最大内存使用率 (0.0-1.0)
     */
    public float getMaxMemoryUsage() {
        return maxMemoryUsage;
    }
    
    /**
     * 获取性能报告
     * @return 性能报告字符串
     */
    public String getPerformanceReport() {
        long runningTime = System.currentTimeMillis() - startTime;
        float averageFPS = totalFrames * 1000.0f / runningTime;
        
        StringBuilder report = new StringBuilder();
        report.append("=== 性能监控报告 ===\n");
        report.append(String.format("运行时间: %.1f秒\n", runningTime / 1000.0f));
        report.append(String.format("总帧数: %d\n", totalFrames));
        report.append(String.format("平均FPS: %.1f\n", averageFPS));
        report.append(String.format("当前FPS: %.1f\n", currentFPS));
        report.append(String.format("平均渲染时间: %.1fms\n", averageRenderTime));
        report.append(String.format("最大渲染时间: %.1fms\n", maxRenderTime));
        report.append(String.format("当前内存使用: %.1f%%\n", currentMemoryUsage * 100));
        report.append(String.format("最大内存使用: %.1f%%\n", maxMemoryUsage * 100));
        report.append(String.format("FPS警告次数: %d\n", fpsWarnings));
        report.append(String.format("渲染时间警告次数: %d\n", renderWarnings));
        report.append(String.format("内存警告次数: %d\n", memoryWarnings));
        
        return report.toString();
    }
    
    /**
     * 获取简化的性能信息（用于HUD显示）
     * @return 简化的性能信息
     */
    public String getSimpleStats() {
        return String.format("FPS: %.0f | 渲染: %.1fms | 内存: %.0f%%", 
            currentFPS, averageRenderTime, currentMemoryUsage * 100);
    }
    
    /**
     * 重置统计数据
     */
    public void reset() {
        startTime = System.currentTimeMillis();
        totalFrames = 0;
        frameCount = 0;
        currentFPS = 0;
        averageRenderTime = 0;
        maxRenderTime = 0;
        renderSampleCount = 0;
        currentMemoryUsage = 0;
        maxMemoryUsage = 0;
        fpsWarnings = 0;
        renderWarnings = 0;
        memoryWarnings = 0;
        
        Log.d(TAG, "性能监控统计已重置");
    }
    
    /**
     * 检查是否有性能问题
     * @return 是否有性能问题
     */
    public boolean hasPerformanceIssues() {
        return currentFPS < FPS_WARNING_THRESHOLD || 
               averageRenderTime > RENDER_WARNING_THRESHOLD ||
               currentMemoryUsage > MEMORY_WARNING_THRESHOLD;
    }
}